# frozen_string_literal: true

class VulnerabilityPresenter < Gitlab::View::Presenter::Delegated
  presents ::Vulnerability, as: :vulnerability

  delegator_override :links
  def links
    vulnerability.links.map(&:with_indifferent_access)
  end

  delegator_override :remediations
  def remediations
    vulnerability.remediations.to_a.compact.map(&:with_indifferent_access)
  end

  def location_text
    return file unless line

    "#{file}:#{line}"
  end

  def location_link_with_raw_path
    location_link_for(raw_path)
  end

  def location_link
    location_link_for(blob_path)
  end

  def raw_path
    return unless file

    path_with_line_number(project_raw_path(vulnerability.project, File.join(pipeline_branch, file)))
  end

  delegator_override :blob_path
  def blob_path
    return unless file

    path_with_line_number(vulnerability.blob_path)
  end

  def scanner
    finding.scanner || {}
  end

  def scan
    finding.scan || {}
  end

  def jira_issue_description
    ApplicationController.render(
      template: 'vulnerabilities/jira_issue_description',
      formats: :md,
      locals: { vulnerability: self }
    )
  end

  delegator_override :description
  def description
    vulnerability.description || finding.description
  end

  def evidence_issue_description
    return if finding.evidence.blank?

    ApplicationController.render(
      template: 'vulnerabilities/evidence_issue_description',
      formats: :md,
      locals: { evidence: finding.evidence }
    ).strip
  end

  private

  def location_link_for(path)
    return location_text unless path

    "#{root_url}#{path}"
  end

  def pipeline_branch
    finding.pipeline_branch
  end

  def path_with_line_number(path)
    return unless path

    path = path.gsub(%r{^/}, '')

    add_line_numbers(path, finding.location['start_line'], finding.location['end_line'])
  end

  def root_url
    Gitlab::Routing.url_helpers.root_url
  end

  def line
    finding.location.dig("start_line")
  end

  def file
    finding.location.dig("file")
  end

  def add_line_numbers(path, start_line, end_line)
    return path unless start_line

    path_with_line_numbers(path, start_line, end_line)
  end
end
